package com.itheima.health.util;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.ListObjectsRequest;
import com.aliyun.oss.model.OSSObjectSummary;
import com.aliyun.oss.model.ObjectListing;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.io.ByteArrayInputStream;
import java.util.HashMap;
import java.util.Map;

@Data
@AllArgsConstructor
@Slf4j
public class AliOssUtil {

    private String endpoint;
    private String accessKeyId;
    private String accessKeySecret;
    private String bucketName;

    /**
     * 文件上传
     *
     * @param bytes 要上传的文件的字节数组
     * @param objectName  上传到OSS后的文件对象名或路径
     * @return 文件路径
     */
    public String upload(byte[] bytes, String objectName) {

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(
                endpoint,
                accessKeyId,
                accessKeySecret);

        try {
            // 创建PutObject请求。
            ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(bytes));
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }

        //文件访问路径规则 https://BucketName.Endpoint/ObjectName
        StringBuilder stringBuilder = new StringBuilder("https://");
        stringBuilder
                .append(bucketName)
                .append(".")
                .append(endpoint)
                .append("/")
                .append(objectName);

        log.info("文件上传到:{}", stringBuilder);

        return stringBuilder.toString();
    }


    /**
     * 获取桶中所有文件
     *
     * @return 桶中图片key-name的Map
     */
    public Map<String, String> listAllFiles() {
        HashMap<String, String> keysMap = new HashMap<>();
        OSS ossClient = new OSSClientBuilder().build(
                endpoint,
                accessKeyId,
                accessKeySecret);

        try {
            // 构造ListObjectsRequest请求
            ListObjectsRequest listObjectsRequest = new ListObjectsRequest(bucketName);

            // 列举存储桶中的所有对象
            ObjectListing objectListing = ossClient.listObjects(listObjectsRequest);

            // 获取桶中name和key
            for (OSSObjectSummary objectSummary : objectListing.getObjectSummaries()) {
                String key = objectSummary.getKey();
                String name = key.substring(key.lastIndexOf("/") + 1);
                keysMap.put(key, name);
            }
        } catch (Exception e) {
            log.error("获取桶中图片的key时出现异常 {}", e.toString());
            throw new RuntimeException(e);
        } finally {
            // 关闭OSS客户端连接
            ossClient.shutdown();
        }
        return keysMap;
    }


    /**
     * 删除未使用的图片文件
     *
     * @param key OSS上图片的唯一key
     */
    public void deleteFile(String key) {
        OSS ossClient = new OSSClientBuilder().build(
                endpoint,
                accessKeyId,
                accessKeySecret);
        try {
            ossClient.deleteObject(bucketName, key);
        } catch (OSSException oe) {
            log.error("删除桶中图片出现异常 {}", oe.toString());
            throw new RuntimeException(oe);
        } catch (ClientException ce) {
            log.error("出现异常 {}", ce.toString());
            throw new RuntimeException(ce);
        } finally {
            // 关闭资源
            ossClient.shutdown();
        }
    }
}
